#ifndef DODO_RUBIK
#define DODO_RUBIK

#include <iostream>
#include <string>
#include <stdio.h>
#include <ncurses.h>
#include <termios.h>
#include <unistd.h>
#include <cstdlib>
#include <ctime>
using namespace std;

    const int cR=1; const int cG=2; const int cB=3; const int cY=4;
    const int cW=5; const int cO=6; const int cK=0;

    const int U=0;  const int D=1;  const int F=2;
    const int B=3;  const int L=4;  const int R=5;
	
    const int ID_oppo=4; const int ID_c0=0; const int ID_c1=1; 
    const int ID_c2=2; const int ID_c3=3;

	const char MoveNames[12]={ 'u','U','d','D','f','F','b','B','l','L','r','R'};
	const char FaceMoveNames[6]={'u','d','f','b','l','r'};
	const char FaceCounterMoveNames[6]={'U','D','F','B','L','R'};
//the data structure
	//      3 0 0   
	//      3 U 1   U=0, D=1, F=2, B=3, L=4, R=5
	//      2 2 1
	//3 0 0 3 0 0 3 0 0 3 0 0
	//3 L 1 3 F 1 3 R 1 3 B 1
	//2 2 1 2 2 1 2 2 1 2 2 1 
	//      3 0 0 
	//      3 D 1
	//      2 2 1

    const int Relation[6][5]={B,R,F,L,D,  F,R,B,L,U,
        U,R,D,L,B,  U,L,D,R,F,  U,F,D,B,R,  U,B,D,F,L};
	const int EdgeCornerR[4]={0,1,2,3};
	const int EdgeCornerL[4]={3,0,1,2};
	const int CornerEdgeR[4]={1,2,3,0};
	const int CornerEdgeL[4]={0,1,2,3};
	const int EdgeEdgeR[4]={1,2,3,0};
	const int EdgeEdgeL[4]={3,0,1,2};

	int TranslateColor(char inchar);
	void Swap4(int &Int0 ,int &Int1,int &Int2, int &Int3, bool oppo=false);
    int FindBack(int face1, int ID_cNum);
/*  struct Face
    {
        int pieces[3,3];
    }; */
	struct PosPair
	{
		int face;
		int pos;
	};
	
    struct Rubik
    {
        int center[6];
        int edge[6][4];
        int corner[6][4];
    };
	void CopyRubik(Rubik &src, Rubik &dest); 
	string RubikToString(Rubik &rbk);
	bool StringToRubik(Rubik &rbk, string posstr);
//  void SetFace(Face &face, int array[9]);
//  void SetRubik(Rubik &rubik, Face u, Face f, Face r, Face l, Face b, Face d);
    void ManuallySetRubik(Rubik &rubik, bool init=false);
    void Turn(Rubik &rbk, int face, bool oppo=false);
	void TurnCenter(Rubik &rbk, int face, bool oppo=false);
	void TurnTotal(Rubik &rbk, int face, bool oppo=false);
	bool TranslateMove(Rubik &rbk, char ch);
	
	bool TurnRubikString(Rubik &rbk, string moves);
	
	int mygetch();
	void RandomRubik(Rubik &rbk);
	void PrintRubikStr(Rubik &rbk);
	void SetRubikWithString(Rubik &rbk);
	void OnHelp();
#endif
